/*
 * WRMTransactionManagementModule.java    ver   27/nov/2009
 *
 * Copyright (c) 2009 mentalsmash.org
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * The use of the Apache License does not indicate that this project is
 * affiliated with the Apache Software Foundation.
 */
package org.mentalsmash.tazio.transactions.management.wrm;

//import java.net.MalformedURLException;
//import java.rmi.Naming;
//import java.rmi.NotBoundException;
//import java.rmi.RemoteException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.mentalsmash.tazio.transactions.UserTransactionManager;
import org.mentalsmash.tazio.transactions.management.BackwardValidationAgent;
import org.mentalsmash.tazio.transactions.management.SystemTransactionManager;
import org.mentalsmash.tazio.transactions.management.TransactionManagementModule;
import org.mentalsmash.tazio.transactions.management.TransactionManagerMonitor;
import org.mentalsmash.tazio.transactions.management.ValidationAgent;
import org.mentalsmash.tazio.transactions.management.rm.RMTransactionsFacade;
import org.mentalsmash.tazio.transactions.modules.Committers;
import org.mentalsmash.tazio.transactions.objects.RootSet;
import org.mentalsmash.tazio.transactions.util.CustomNameThreadFactory;

import com.google.inject.Scope;
import com.google.inject.Scopes;
import com.google.inject.name.Names;

/**
 * @version ver 27/nov/2009
 * @author Andrea Reale <andrea.reale@gmail.com>
 * 
 */
public class WRMTransactionManagementModule extends TransactionManagementModule {

    private final static int COMMITTERS_POOL_SIZE = 5;
    /**
     * When the commit request does not return a repsonse, a WATT message is sent.
     * This timeout is used to resend another WATT message if the first's result was ACTIVE
     */
    private final static int WAIT_BEFORE_RETRY_ACTIVE = 200;
    /**
     * When the commit request does not return a repsonse, a WATT message is sent.
     * This timeout is used to resend another WATT message if the first's result was UNKNOWN
     */
    private final static int WAIT_BEFORE_RETRY_UNKNOWN = 500;
    /**
     * Number of WATT retries
     */
    private final static int NUM_RETRIES = 3;

//    private final static String NAME = "//localhost:4242/replica-manager-1";
//    private RMTransactionsFacade rmiFacade;
//    private RootSet rmiRs;

    public WRMTransactionManagementModule(String name) {
	super(name);
	
	
//	try {
//	    rmiFacade = (RMTransactionsFacade) Naming.lookup(NAME);
//	    rmiRs = rmiFacade.getRootSet();
//
//	} catch (final MalformedURLException e) {
//	    e.printStackTrace();
//	} catch (final RemoteException e) {
//	    e.printStackTrace();
//	} catch (final NotBoundException e) {
//	    e.printStackTrace();
//	}

    }

    @Override
    protected void configure() {

	super.configure();

	bind(SystemTransactionManager.class).to(WRMTransactionManager.class);
	bind(UserTransactionManager.class).to(WRMTransactionManager.class);

	// bind(RMTransactionsFacade.class).to(RMTransactionsFacadeProxy.class);
	// for RMI
	
	bind(RMTransactionsFacade.class).toProvider(RemoteRMFacadeProvider.class).in(Scopes.SINGLETON);
	bind(RootSet.class).toProvider(WRMRootSetProvider.class).in(Scopes.SINGLETON);

	bind(ExecutorService.class).annotatedWith(Committers.class).toInstance(
		Executors.newFixedThreadPool(COMMITTERS_POOL_SIZE,
			new CustomNameThreadFactory("committer-thread")));

	bind(RMValidator.class).to(RemoteValidator.class);
	bind(ValidationAgent.class).to(BackwardValidationAgent.class);

	bindConstant().annotatedWith(Names.named("RMValidatorWaitActive")).to(
		WAIT_BEFORE_RETRY_ACTIVE);
	bindConstant().annotatedWith(Names.named("RMValidatorWaitUnknown")).to(
		WAIT_BEFORE_RETRY_UNKNOWN);
	bindConstant().annotatedWith(Names.named("RMValidatorNumRetries")).to(
		NUM_RETRIES);

	bind(TransactionManagerMonitor.class).to(
		WRMTransactionManagerMonitor.class);
    }
}
